package com.sz.common.base.dao.ext.impl;

import com.sz.common.base.dao.Dao;
import com.sz.common.base.dao.ext.DaoExt;
import com.sz.common.base.dao.ext.FieldExp;
import com.sz.common.base.utils.TypeConversionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Package: com.sz.common.base.dao.ext.impl <br>
 * Function: TODO: ADD FUNCTION <br>
 * Author: Charles. <br>
 * Date: 2017-02-22 09:59:00.
 */
@Service
public class DaoExtSupport implements DaoExt {
    @Autowired
    protected Dao dao;

    @Override
    public Dao getDao() {
        return this.dao;
    }


    /**
     * @param tableName --表名
     * @param fields    --field values
     * @return --返回新主键
     */
    @Override
    public Object insertData(String tableName, final List<FieldExp> fields) {
        if (tableName == null || tableName.trim().length() == 0) {
            throw new IllegalArgumentException("tableName cannot be empty");
        }
        if (fields == null || fields.size() == 0) {
            throw new IllegalArgumentException("fields cannot be empty");
        }
        List<List<FieldExp>> list = new ArrayList<>();
        list.add(fields);

        List<Object> ids = this.insertDataBatch(tableName, list);
        if (ids != null && ids.size() > 0) {
            return ids.get(0);
        }
        return null;
    }

    /**
     * @param tableName --表名
     * @param list      --field values
     * @return --返回新主键
     */
    @Override
    public List<Object> insertDataBatch(String tableName, final List<List<FieldExp>> list) {
        if (tableName == null || tableName.trim().length() == 0) {
            throw new IllegalArgumentException("tableName cannot be empty");
        }
        if (list == null || list.size() == 0) {
            throw new IllegalArgumentException("fields cannot be empty");
        }

        List<Map<String, Object>> parasList = new ArrayList<>();
        for (List<FieldExp> fields : list) {
            Map<String, Object> paras = new HashMap<>();
            paras.put("tableName", tableName);
            paras.put("fields", fields);
            parasList.add(paras);
        }

        if (parasList.size() == 1) {
            this.dao.save("commonInsert", parasList.get(0));
        } else {
            this.dao.batchInsert("commonInsert", parasList);
        }

        List<Object> ids = new ArrayList<>();
        for (Map<String, Object> paras : parasList) {
            ids.add(paras.get("id"));
        }
        return ids;
    }


    /**
     * 更新数据
     * 如果需要更新字段值为null，请在schema中指明对应字段的JDBC类型
     *
     * @param tableName   --数据表结构
     * @param fields      --更新字段值
     * @param whereFields --where字段值
     */
    @Override
    public void updateData(String tableName, final List<FieldExp> fields, final List<FieldExp> whereFields) {
        if (fields == null || fields.size() == 0) {
            throw new IllegalArgumentException("field values cannot be empty");
        }

        List<List<FieldExp>> fieldsList = new ArrayList<>();
        List<List<FieldExp>> whereFieldsList = new ArrayList<>();
        fieldsList.add(fields);
        whereFieldsList.add(whereFields);
        this.updateDataBatch(tableName, fieldsList, whereFieldsList);
    }

    /**
     * 更新数据
     * 如果需要更新字段值为null，请在schema中指明对应字段的JDBC类型
     *
     * @param tableName       --数据表结构
     * @param fieldsList      --更新字段值
     * @param whereFieldsList --where字段值
     */
    @Override
    public void updateDataBatch(String tableName, final List<List<FieldExp>> fieldsList,
                                final List<List<FieldExp>> whereFieldsList) {
        if (tableName == null || tableName.trim().length() == 0) {
            throw new IllegalArgumentException("tableName cannot be empty");
        }
        if (fieldsList == null || fieldsList.size() == 0) {
            throw new IllegalArgumentException("field values cannot be empty");
        }
        if (whereFieldsList == null || whereFieldsList.size() != fieldsList.size()) {
            throw new IllegalArgumentException("where conditions does not match fields list size");
        }

        List<Map<String, Object>> parasList = new ArrayList<>();
        for (int i = 0; i < fieldsList.size(); i++) {
            List<FieldExp> fields = fieldsList.get(i);
            List<FieldExp> whereFields = whereFieldsList.get(i);

            Map<String, Object> paras = new HashMap<>();
            paras.put("tableName", tableName);
            paras.put("fields", fields);
            paras.put("where", whereFields == null ? new ArrayList<FieldExp>() : whereFields);

            parasList.add(paras);
        }

        if (parasList.size() == 1) {
            this.dao.update("commonUpdate", parasList.get(0));
        } else {
            this.dao.batchUpdate("commonUpdate", parasList);
        }
    }

    /**
     * 删除数据
     *
     * @param tableName   --数据表结构
     * @param whereFields --where字段值
     */
    @Override
    public void deleteData(String tableName, final List<FieldExp> whereFields) {
        List<List<FieldExp>> whereFieldsList = new ArrayList<>();
        whereFieldsList.add(whereFields);

        this.deleteDataBatch(tableName, whereFieldsList);
    }

    /**
     * 删除数据
     *
     * @param tableName       --数据表结构
     * @param whereFieldsList --where字段值
     */
    @Override
    public void deleteDataBatch(String tableName, final List<List<FieldExp>> whereFieldsList) {
        if (tableName == null || tableName.trim().length() == 0) {
            throw new IllegalArgumentException("tableName cannot be empty");
        }
        if (whereFieldsList == null || whereFieldsList.size() == 0) {
            return;
        }

        List<Map<String, Object>> parasList = new ArrayList<>();
        for (List<FieldExp> whereFields : whereFieldsList) {

            Map<String, Object> paras = new HashMap<>();
            paras.put("tableName", tableName);
            paras.put("where", whereFields == null ? new ArrayList<FieldExp>() : whereFields);

            parasList.add(paras);
        }

        if (parasList.size() == 1) {
            this.dao.delete("commonDelete", parasList.get(0));
        } else {
            this.dao.batchDelete("commonDelete", parasList);
        }
    }

    /**
     * 删除数据
     *
     * @param tableName --数据表结构
     * @param keyName   --关键字段
     * @param idArray   --where字段值
     */
    @Override
    public void deleteDataByKeys(String tableName, String keyName, final Serializable[] idArray) {
        if (tableName == null || tableName.trim().length() == 0) {
            throw new IllegalArgumentException("tableName cannot be empty");
        }
        if (keyName == null || keyName.trim().length() == 0) {
            throw new IllegalArgumentException("keyName cannot be empty");
        }
        if (idArray == null || idArray.length == 0) {
            return;
        }

        Map<String, Object> paras = new HashMap<>();
        paras.put("tableName", tableName);
        paras.put("keyName", keyName);
        paras.put("ids", idArray);

        this.dao.delete("commonDeleteByKeys", paras);
    }

    /**
     * @param tableName
     * @param returnFields
     * @param whereFields
     * @return
     */
    @Override
    public List<Map> selectDataList(String tableName, List<String> returnFields, final List<FieldExp> whereFields) {
        if (tableName == null || tableName.trim().length() == 0) {
            throw new IllegalArgumentException("tableName cannot be empty");
        }
        Map<String, Object> paras = new HashMap<>();
        paras.put("tableName", tableName);
        paras.put("where", whereFields == null ? new ArrayList<FieldExp>() : whereFields);
        if (returnFields != null && returnFields.size() > 0) {
            paras.put("fieldNames", returnFields);
        }

        List<Map> list = this.dao.findForList("commonSelect", paras, Map.class);
        return list;
    }

    /**
     * @param tableName
     * @param returnFields
     * @param whereFields
     * @return
     */
    @Override
    public Map selectDataObject(String tableName, List<String> returnFields, final List<FieldExp> whereFields) {
        if (tableName == null || tableName.trim().length() == 0) {
            throw new IllegalArgumentException("tableName cannot be empty");
        }
        Map<String, Object> paras = new HashMap<>();
        paras.put("tableName", tableName);
        paras.put("where", whereFields == null ? new ArrayList<FieldExp>() : whereFields);
        if (returnFields != null && returnFields.size() > 0) {
            paras.put("fieldNames", returnFields);
        }

        Map map = (Map) this.dao.findForObject("commonSelect", paras);
        return map;
    }

    /**
     * @param tableName
     * @param whereFields
     * @return
     */
    @Override
    public long selectCount(String tableName, final List<FieldExp> whereFields) {
        List<String> returnFields = new ArrayList<>();
        returnFields.add("count(*) as num");
        Map map = selectDataObject(tableName, returnFields, whereFields);
        if (map != null && map.size() > 0) {
            Object obj = map.get("num");
            Long lobj = TypeConversionUtils.covertTo(obj, Long.class);
            return lobj == null ? 0 : lobj;
        }
        return 0;
    }
}
